﻿Imports System.ComponentModel

Public Class frmSysManageLedgers

    Private m_curLedgerEditor As ClsLedgerEditor '当前正在编辑或输入的账套
    Private m_editState As Int16 '当前窗体编辑状态，0 - 浏览，1 - 新增，2 - 编辑
    Private m_curRow As Int32 '当前列表所在行，未选中时为 -1
    Private m_ifEditing As Boolean '当前编辑区数据是否修改的标识
    Private m_dirty As Boolean '当前是否有数据修改
    Private m_saving As Boolean '当前是否正在保存数据

    '定义一个委托，用来将账套对象加入到列表中
    Private Delegate Sub PushLedgerToList(ByVal ledger As ClsLedgerEditor)
    Private m_pushLedger As PushLedgerToList = New PushLedgerToList(AddressOf AddOneLedgerToList)
    '定义一个委托，用来将用户对象加入到用户列表中
    Private Delegate Sub AddUserToListView(ByVal user As ClsUser)
    Private m_addUserToListView As AddUserToListView = New AddUserToListView(AddressOf AddOneUserTListView)
    '定义一个委托，用来在数据保存到表中以后修改列表中的内容，
    Private Delegate Sub EditLedgerInList(ByVal ledger As ClsLedger)
    Private m_editLedger As EditLedgerInList
    '定义一个委托，用来从listview控件中删除一行数据
    Private Delegate Sub DeleteRowFromListView(ByVal mRow As Integer)
    Private m_deleteRow As DeleteRowFromListView = New DeleteRowFromListView(AddressOf DeleteRow)

    '定义一个委托，用来在数据保存完毕后通知窗体进程
    Private Delegate Sub SaveDoneDelegate()
    Private m_SaveDone As SaveDoneDelegate = New SaveDoneDelegate(AddressOf SaveLedgerDone)
    '定义一个委托，用来在主窗体上显示 当前的工作进程信息
    Private Delegate Sub SetNotifyInfo(ByVal s As String)
    Private m_ShowNotify As SetNotifyInfo = New SetNotifyInfo(AddressOf sysFrmMdiMain.SetNotifyText)

    '全部账套的集合列表
    Private m_ledgerList As List(Of ClsLedger)
    Private m_ledgerEditList As List(Of ClsLedgerEditor)

    '定义一个中间订阅变量，关注编辑区控件内容修改
    Private m_broker As ClsBroker

    '全部用户集合列表
    Private m_userList As List(Of ClsUser)

    '新建账套的模板类对象
    Private m_IndustryAcctType As ClsIndustryAccountType
    Private m_IndustryAcctList As List(Of ClsIndustryAccount)

    Private Sub frmSysManageLedgers_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        '为窗体变量赋初值 
        m_curLedgerEditor = Nothing
        m_editState = 0
        m_curRow = -1

        '窗体集合列表
        m_userList = New List(Of ClsUser)
        m_ledgerEditList = New List(Of ClsLedgerEditor)
        m_ledgerList = New List(Of ClsLedger)

        '委托变量赋值
        'm_pushLedger = New PushLedgerToList(AddressOf AddOneLedgerToList)

        '订阅变量赋值并开启订阅
        m_broker = New ClsBroker()
        AddHandler ClsBroker.OnCustomCtrolContentChange, AddressOf CurLedgerEdited

        AddHandler ClsBroker.OnChange, AddressOf AddNewUserDone

        AddHandler ClsBroker.OnChange, AddressOf SelectedIndustryTemplate

        '检查当前状态
        CheckCurrentState()

        '初始化列表标题
        InitialLedgerListViewHeder()

        InitialUserListHeader()

        '载入数据到列表中
        LoadLedgersToList()

    End Sub

    Private Sub CurLedgerEdited(ByVal sender As Object, ByVal e As CustomControlChangeNotifyEventArg)
        '用来订阅的回调过程
        If Not e.FormWehere.Equals(Me.Name) Then
            Return
        End If
        '标识 当前编辑区控件内容已修改
        'm_ifEditing = True
        m_dirty = True
        '检查保存状态
        If m_editState <> 0 Then
            Me.btnSaveLedger.Enabled = True
        End If

    End Sub

    ''' <summary>
    ''' 检查当前编辑状态，改变按钮状态和文字
    ''' </summary>
    Private Sub CheckButtonState()
        Select Case m_editState
            Case 0 ' 浏览 
                '当前编辑标识
                m_ifEditing = False
                '检查当前按钮区状态
                Me.btnAddLedger.Enabled = True
                Me.btnSaveLedger.Enabled = False
                If m_curLedgerEditor IsNot Nothing Then
                    Me.btnModifyLedger.Enabled = True
                    Me.btnDeleteLedger.Enabled = True
                Else
                    Me.btnModifyLedger.Enabled = False
                    Me.btnDeleteLedger.Enabled = False
                End If
                Me.btnInput.Enabled = True
                'Me.btnClose.Enabled = True

                Me.btnAddLedger.Text = "新增账套"
                Me.btnModifyLedger.Text = "编辑账套"
            Case 1 '新增
                '当前编辑标识
                m_ifEditing = True
                '检查当前按钮区状态
                'Me.btnAddLedger.Enabled = False '新增 禁止
                '新增按钮修改为 取消新增
                Me.btnAddLedger.Text = "取消新增"
                '开启保存按钮，保存成功后，新增按钮标题挽回原标题
                '
                'If m_dirty Then
                '    If MessageBox.Show("数据已修改，是否需要保存？", "新建账套 - 保存提醒", MessageBoxButtons.YesNo) = DialogResult.No Then

                '    End If
                'End If
                Me.btnSaveLedger.Enabled = True  'm_ifEditing  
                Me.btnModifyLedger.Enabled = False  '修改禁止
                Me.btnDeleteLedger.Enabled = False '删除禁止
                Me.btnInput.Enabled = False

            Case 2 '修改
                '当前编辑标识
                m_ifEditing = True
                '检查当前按钮区状态
                Me.btnModifyLedger.Text = "取消编辑"

                Me.btnAddLedger.Enabled = False '新增 禁止
                Me.btnSaveLedger.Enabled = True  'm_ifEditing  '保存禁止
                Me.btnModifyLedger.Enabled = True  '修改禁止
                Me.btnDeleteLedger.Enabled = False '删除禁止
                Me.btnInput.Enabled = False
        End Select

        '判断当前是否正在保存
        If m_saving Then
            '禁止全部
            Me.btnAddLedger.Enabled = False
            'Me.btnClose.Enabled = False
            Me.btnDeleteLedger.Enabled = False
            Me.btnSaveLedger.Enabled = False
            Me.btnModifyLedger.Enabled = False
            Me.btnInput.Enabled = False
        Else
            'Me.btnClose.Enabled = True
        End If
    End Sub

    Private Sub CheckTextBoxState()
        Select Case m_editState
            Case 0 ' 浏览 
                '检查当前编辑区状态
                Me.txtLedgerName.ReadOnly = True
                Me.txtCompanyName.ReadOnly = True
                '检查是否可以编辑
                If m_curLedgerEditor IsNot Nothing Then
                    Me.txtLedgerId.Text = m_curLedgerEditor.LedgerClass.LedgerId
                    Me.txtLedgerName.Text = m_curLedgerEditor.LedgerClass.LedgerName
                    Me.txtLedgerRealPath.Text = m_curLedgerEditor.LedgerClass.LedgerDataRealPath
                    Me.txtCompanyName.Text = m_curLedgerEditor.LedgerClass.LedgerCompanyName

                End If
            Case 1 '新增
                '检查当前编辑区状态
                Me.txtLedgerName.Text = ""
                Me.txtLedgerName.ReadOnly = False
                Me.txtCompanyName.Text = ""
                Me.txtCompanyName.ReadOnly = False
            Case 2 '修改
                '检查当前编辑区状态
                Me.txtLedgerName.ReadOnly = False
                Me.txtCompanyName.ReadOnly = False
        End Select

        If m_saving Then
            Me.txtLedgerName.ReadOnly = True
            Me.txtCompanyName.ReadOnly = True
        End If
    End Sub

    Private Sub CheckCurrentState()
        '检查按钮状态
        CheckButtonState()
        '检查编辑框状态
        CheckTextBoxState()
    End Sub

    Private Sub InitialUserListHeader()
        '初始化列表标题
        Dim header1 As ColumnHeader = New ColumnHeader()
        header1.Text = "编号"
        header1.Width = 50
        header1.TextAlign = HorizontalAlignment.Center
        header1.Name = "hUserId"

        Dim header2 As ColumnHeader = New ColumnHeader()
        With header2
            .Text = "登录名称"
            .Width = 100
            .TextAlign = HorizontalAlignment.Left
            .Name = "hUserName"

        End With

        With Me.lstUserLedger
            .FullRowSelect = True '行选择模式
            .MultiSelect = True '不允许 多行选择
            .View = View.Details '视图选项：详细模式
            '.Width = Me.FlowLayoutPanel1.Width  '宽度占满窗体
            .HeaderStyle = ColumnHeaderStyle.Nonclickable '标题不可点击
            .Columns.Add(header1)
            .Columns.Add(header2)
            '根据内容调整列宽
            'ListView.AutoResizeColumns(ColumnHeaderAutoResizeStyle.ColumnContent); 
            'ListView.AutoResizeColumns(ColumnHeaderAutoResizeStyle.HeaderSize);
        End With

    End Sub
    ''' <summary>
    ''' 初始化账套列表listview表头
    ''' </summary>
    Private Sub InitialLedgerListViewHeder()
        '初始化列表标题
        Dim header1 As ColumnHeader = New ColumnHeader()
        header1.Text = "编号"
        header1.Width = 50
        header1.TextAlign = HorizontalAlignment.Center
        header1.Name = "hLedgerId"

        Dim header2 As ColumnHeader = New ColumnHeader()
        With header2
            .Text = "账套名称"
            .Width = 100
            .TextAlign = HorizontalAlignment.Left
            .Name = "hLedgerName"

        End With

        Dim header3 As ColumnHeader = New ColumnHeader()
        With header3
            .Text = "公司名称"
            .Width = 160
            .TextAlign = HorizontalAlignment.Left
            .Name = "hLedgerCompanyName"
            '.AutoResize = True
        End With

        Dim header4 As ColumnHeader = New ColumnHeader()
        With header4
            .Text = "路径名称"
            .Width = 120
            .TextAlign = HorizontalAlignment.Left
            .Name = "hLedgerRealPath"
        End With

        Dim header5 As ColumnHeader = New ColumnHeader()
        With header5
            .Text = "启用"
            .Width = 50
            .TextAlign = HorizontalAlignment.Center
            .Name = "hLederOpened"
        End With

        Dim header6 As ColumnHeader = New ColumnHeader()
        With header6
            .Text = "凭证"
            .Width = 50
            .TextAlign = HorizontalAlignment.Center
            .Name = "hLedgerHaveVoucher"
        End With

        With Me.lstLedgers
            .FullRowSelect = True '行选择模式
            .MultiSelect = True '不允许 多行选择
            .View = View.Details '视图选项：详细模式
            .Width = Me.FlowLayoutPanel1.Width  '宽度占满窗体
            .HeaderStyle = ColumnHeaderStyle.Nonclickable '标题不可点击
            .Columns.Add(header1)
            .Columns.Add(header2)
            .Columns.Add(header3)
            .Columns.Add(header4)
            .Columns.Add(header5)
            .Columns.Add(header6)
            '根据内容调整列宽
            'ListView.AutoResizeColumns(ColumnHeaderAutoResizeStyle.ColumnContent); 
            'ListView.AutoResizeColumns(ColumnHeaderAutoResizeStyle.HeaderSize);
        End With
    End Sub

    Private Sub LoadLedgersToList()
        '载入全部账套数据，并加入到列表中
        '赋值委托
        m_pushLedger = New PushLedgerToList(AddressOf AddOneLedgerToList)

        '多线程处理
        Dim t As Threading.Thread = New Threading.Thread(AddressOf LoadLedgersFromDb)
        t.Start()

    End Sub

    Private Sub LoadLedgersFromDb()
        Try
            '从数据库取出数据
            '账套信息类操作
            Dim tmpDbAccess As ClsLedgerDbAccess = New ClsLedgerDbAccess(sysAppInfoConnectionString)
            Dim tmpLedgerList = tmpDbAccess.GetAllLedger()
            '账套参数类操作
            Dim tmpLedgerSettingDb As ClsTLedgerSettingDbAccess '= New ClsTLedgerSettingDbAccess()
            Dim tmpUserDbConnectionString As String
            Dim tmpLedgerOpen As Boolean
            Dim tmpVoucherDb As ClsTVoucherDbAccess
            Dim tmpHaveVoucher As Boolean
            '账套相关用户操作
            Dim tmpUL As List(Of ClsUserLedger)
            Dim tmpRDb As ClsUserLedgerDbAccess = New ClsUserLedgerDbAccess(sysAppInfoConnectionString)

            'Dim tmpUserList As List(Of ClsUser)
            Dim tmpUDb As ClsUserDbAccess = New ClsUserDbAccess(sysAppInfoConnectionString)
            '取出全部用户列表
            m_userList = tmpUDb.GetAllUser()

            Dim tmpUserIdS As List(Of Int32)
            '转换为LedgerEditor类集合
            For Each tmpL As ClsLedger In tmpLedgerList
                '验证是否已存在，如果存在则打开用户账套库取出账套参数信息
                '构建 账套读取字串
                tmpUserDbConnectionString = String.Format(sysConnectionTemplate, IO.Path.Combine(IO.Path.Combine(sysAppCurrentPath, APP_DATA_PATH), tmpL.LedgerDataRealPath))
                '读取是否启用
                tmpLedgerSettingDb = New ClsTLedgerSettingDbAccess(tmpUserDbConnectionString)
                tmpLedgerOpen = tmpLedgerSettingDb.GetIfOpenByLedgerId(tmpL.LedgerId)
                '读取全部管理用户
                tmpUL = tmpRDb.GetUsersByLedgerId(tmpL.LedgerId)
                tmpUserIdS = New List(Of Integer)
                Dim tmpUserIdString As String = ""
                For Each ul As ClsUserLedger In tmpUL
                    tmpUserIdString &= ul.UserId.ToString
                    tmpUserIdString &= ","
                    tmpUserIdS.Add(ul.UserId)
                Next

                '判断是否有管理用户
                If String.IsNullOrEmpty(tmpUserIdString) Then
                    '没有
                Else

                    tmpUserIdString = tmpUserIdString.Substring(0, tmpUserIdString.Length - 1)
                End If
                'tmpUserList = tmpUDb.GetUserByIdString(tmpUserIdString)

                '读取是否有凭证
                tmpVoucherDb = New ClsTVoucherDbAccess(tmpUserDbConnectionString)
                tmpHaveVoucher = tmpVoucherDb.GetIfHaveVoucher()
                Dim tmpLedgerE As ClsLedgerEditor = New ClsLedgerEditor()
                tmpLedgerE.IfOpened = tmpHaveVoucher
                tmpLedgerE.IfHaveVoucher = tmpHaveVoucher
                tmpLedgerE.LedgerClass = tmpL
                'tmpLedgerE.UserList = tmpUserList
                tmpLedgerE.UserIdS = tmpUserIdS
                'tmpLedgerE.UserIdString = tmpUserIdString

                '添加到窗体集合中
                If m_ledgerEditList Is Nothing Then
                    m_ledgerEditList = New List(Of ClsLedgerEditor)
                End If
                m_ledgerEditList.Add(tmpLedgerE)
            Next

            '如果有
            If m_ledgerEditList IsNot Nothing Then

                '加入到列表
                For Each tmpEL As ClsLedgerEditor In m_ledgerEditList
                    'm_pushLedger(tmpL)
                    Me.Invoke(m_pushLedger, New Object() {tmpEL})
                Next
            End If

            '取出全部用户列表并加入到用户listview列表中
            If m_userList IsNot Nothing Then

                For Each tmpU As ClsUser In m_userList

                    Me.Invoke(m_addUserToListView, New Object() {tmpU})
                Next
            End If

        Catch ex As OleDb.OleDbException
            mErrorCreater = "frmSysManageLedgers - LoadLedgersToList"
            mErrorNumber = ex.ErrorCode
            mErrorMessage = ex.Message
        End Try
    End Sub

    ''' <summary>
    ''' 将一个用户对象添加到用户listview
    ''' </summary>
    ''' <param name="u">ClsUser对象</param>
    Private Sub AddOneUserTListView(ByVal u As ClsUser)
        '将一个 账套变量 加入到列表中
        Dim tmpItem As ListViewItem = New ListViewItem(u.UserId.ToString)

        'tmpItem.SubItems.Add(u.UserId.ToString)
        tmpItem.SubItems.Add(u.UserName)

        Me.lstUserLedger.Items.Add(tmpItem)
    End Sub

    ''' <summary>
    ''' 加入一个对象到列表中
    ''' </summary>
    ''' <param name="l">ClsLedger类对象</param>
    Private Sub AddOneLedgerToList(ByVal l As ClsLedgerEditor)
        '将一个 账套变量 加入到列表中
        Dim tmpItem As ListViewItem = New ListViewItem(l.LedgerClass.LedgerId.ToString)

        tmpItem.SubItems.Add(l.LedgerClass.LedgerName)
        tmpItem.SubItems.Add(l.LedgerClass.LedgerCompanyName)
        tmpItem.SubItems.Add(l.LedgerClass.LedgerDataRealPath)
        If l.IfOpened Then

            tmpItem.SubItems.Add("是")
        Else
            tmpItem.SubItems.Add("否")
        End If
        If l.IfHaveVoucher Then
            tmpItem.SubItems.Add("有")
        Else
            tmpItem.SubItems.Add("无")
        End If

        Me.lstLedgers.Items.Add(tmpItem)

    End Sub

    Private Sub EditCurrentLedgerInList(ByVal l As ClsLedgerEditor)
        If m_curRow = -1 Then
            Return
        End If

        '将当前选择行的内容修改为类对象内容

        Dim curItem As ListViewItem = Me.lstLedgers.Items(m_curRow)
        curItem.Text = l.LedgerClass.LedgerId.ToString()
        curItem.SubItems(1).Text = l.LedgerClass.LedgerName
        curItem.SubItems(2).Text = l.LedgerClass.LedgerCompanyName
        'curItem.SubItems(0).Text = l.LedgerClass.LedgerDataRealPath
        curItem.SubItems(3).Text = l.LedgerClass.LedgerDataRealPath
        curItem.SubItems(4).Text = IIf(l.IfOpened, "是", "否")
        curItem.SubItems(5).Text = IIf(l.IfHaveVoucher, "有", "无")
    End Sub

    Private Sub frmSysManageLedgers_Closing(sender As Object, e As CancelEventArgs) Handles Me.Closing
        '判断是否正在存储中
        If m_saving Then
            MessageBox.Show("有数据正在存储中，不能退出，请稍后再试。", "账套管理")
            e.Cancel = True
        End If

        '移除订阅事件
        RemoveHandler ClsBroker.OnCustomCtrolContentChange, AddressOf CurLedgerEdited

        '去除回调订阅
        RemoveHandler ClsBroker.OnChange, AddressOf AddNewUserDone
    End Sub

    Private Sub lstLedgers_SelectedIndexChanged(sender As Object, e As EventArgs) Handles lstLedgers.SelectedIndexChanged
        '取出当前选择行
        Dim selItem As ListView.SelectedListViewItemCollection = Me.lstLedgers.SelectedItems

        If selItem.Count < 1 Then
            Return
        End If
        m_curRow = selItem.Item(0).Index
        m_curLedgerEditor = m_ledgerEditList.Item(m_curRow)  'm_ledgerList.Item(m_curRow)
        '填充到控件
        With m_curLedgerEditor.LedgerClass

            Me.txtLedgerId.Text = .LedgerId
            Me.txtLedgerName.Text = .LedgerName
            Me.txtCompanyName.Text = .LedgerCompanyName
            Me.txtLedgerRealPath.Text = .LedgerDataRealPath
        End With

        CheckCurrentState()

        '选择当前账套的管理用户列表，并更新管理用户列表
        '刷新用户列表
        CheckUserForLedger(m_curLedgerEditor.UserIdS)

    End Sub

    Private Sub CheckUserForLedger(ByVal l As List(Of Integer))
        Dim tmpId As Integer
        For Each item As ListViewItem In Me.lstUserLedger.Items

            tmpId = Integer.Parse(item.SubItems(0).Text)
            If l Is Nothing Then
                item.Checked = False
            Else
                If l.Contains(Integer.Parse(tmpId)) Then
                    item.Checked = True
                Else
                    item.Checked = False
                End If
            End If
        Next

    End Sub

    Private Sub btnAddLedger_Click(sender As Object, e As EventArgs) Handles btnAddLedger.Click
        '弹出账套模板选择窗体，如果未选择，则不能新建

        '新增账套按钮
        If m_editState <> 1 Then
            '第一次按
            '判断新增模板是否存在，如果不存在，则弹出窗体让用户选择。
            If m_IndustryAcctType Is Nothing Then
                Dim tmpSelForm As frmIndustryAcctSelect = New frmIndustryAcctSelect()
                Dim frmRet As Int16 = tmpSelForm.ShowDialog()
                'If tmpSelForm.ShowDialog() = DialogResult.No Then
                If frmRet = DialogResult.No Then
                    MessageBox.Show("新建账套必须选择一个行业模板。", "账套管理 - 新建账套")
                    Return
                End If
            End If
            '修改状态
            m_editState = 1 '新增
        Else
            '第二次按
            m_editState = 0 '取消
        End If
        '检查控件
        CheckCurrentState()
    End Sub

    Private Sub SaveLedgerDone()
        '将当前新的ClsLedgerEditor变量加入到集合中
        If m_ledgerEditList Is Nothing Then
            m_ledgerEditList = New List(Of ClsLedgerEditor)
        End If
        If m_editState = 1 And m_curLedgerEditor IsNot Nothing Then
            m_ledgerEditList.Add(m_curLedgerEditor)
        End If
        '恢复变量

        If m_editState = 1 Then
            AddOneLedgerToList(m_curLedgerEditor)
        End If
        If m_editState = 2 Then
            EditCurrentLedgerInList(m_curLedgerEditor)
        End If

        '当前编辑状态
        m_editState = 0 '浏览模式
        '当前保存状态
        m_saving = False

        CheckCurrentState()

    End Sub

    Private Sub btnModifyLedger_Click(sender As Object, e As EventArgs) Handles btnModifyLedger.Click
        '判断当前账套变量
        If m_curLedgerEditor Is Nothing Then
            Return
        End If
        If m_editState <> 2 Then

            m_editState = 2 '修改
        Else
            m_editState = 0 '恢复编辑
        End If
        '检查控件
        CheckCurrentState()

    End Sub

    Private Sub btnSaveLedger_Click(sender As Object, e As EventArgs) Handles btnSaveLedger.Click
        Dim tmpBeginTime As DateTime = Now()
        Debug.Print("保存账套开始：" & tmpBeginTime.ToLongTimeString)

        '保存账套
        '取出内容，调用
        '此时修改realPath
        Dim tmpRealPath As String
        Dim tmpLedgerName As String = Me.txtLedgerName.Text.Trim()
        If String.IsNullOrEmpty(tmpLedgerName) Then
            MessageBox.Show("账套名称必须填写。", "账套管理")
            Return
        End If
        '判断账套名称是否重复
        Dim tmpNameCon As Boolean

        For Each le As ClsLedgerEditor In m_ledgerEditList
            If le.LedgerClass.LedgerName.Equals(tmpLedgerName) Then
                tmpNameCon = True
                Exit For
            End If
        Next
        If tmpNameCon Then
            MessageBox.Show("账套名称重复！请重新填写。", "账套管理")
            Return
        End If
        Dim tmpLedgerCompanyName As String = Me.txtCompanyName.Text.Trim()
        If String.IsNullOrEmpty(tmpLedgerCompanyName) Then
            MessageBox.Show("账套所属公司名称必须填写。", "账套管理")
            Return
        End If
        '修改控件状态
        m_saving = True
        CheckCurrentState()
        '取出账套名称，转换成拼音路径名称
        Dim pinyinS = GetPinYin(tmpLedgerName)
        If pinyinS.Length > 150 Then
            pinyinS = pinyinS.Substring(0, 150)
        End If
        tmpRealPath = "l_" & pinyinS & ".mdb"

        Me.txtLedgerRealPath.Text = tmpRealPath
        '控件内容保存到类对象中
        '判断是新增还是修改
        If m_editState = 1 Then
            '新增
            m_curLedgerEditor = New ClsLedgerEditor()
            Dim tmpC As ClsLedger = New ClsLedger()
            tmpC.LedgerId = 0
            tmpC.LedgerDataRealPath = tmpRealPath '临时
            m_curLedgerEditor.LedgerClass = tmpC
            m_curLedgerEditor.IfOpened = False
            m_curLedgerEditor.IfHaveVoucher = False
        End If
        m_curLedgerEditor.LedgerClass.LedgerName = tmpLedgerName
        m_curLedgerEditor.LedgerClass.LedgerCompanyName = tmpLedgerCompanyName

        Debug.Print("准备工作结束 ，共花：" & (Now() - tmpBeginTime).TotalSeconds)


        '保存内容到库中
        Dim t As Threading.Thread = New Threading.Thread(AddressOf SaveLedgerToDb)
        t.Start(m_curLedgerEditor)

    End Sub

    Private Sub SaveLedgerToDb(ByVal l As ClsLedgerEditor)
        'Dim tmpBeginTime As DateTime = Now()
        'Debug.Print("写入数据库中开始：" & tmpBeginTime.ToShortTimeString)

        Try

            '更新主窗体的通知内容
            sysFrmMdiMain.Invoke(m_ShowNotify, "保存账套到数据表中...")
            '
            Dim tmpDbAccess As ClsLedgerDbAccess = New ClsLedgerDbAccess(sysAppInfoConnectionString)
            Dim ifInsert As Boolean = False
            Dim ifRet As Int32

            If m_editState = 1 Then
                ifInsert = True
                ifRet = tmpDbAccess.InsertLedger(m_curLedgerEditor.LedgerClass)
            Else
                ifRet = tmpDbAccess.UpdateLedger(m_curLedgerEditor.LedgerClass) '.InsertLedger(m_curLedgerEditor.LedgerClass)
            End If


            'Dim tmpD1 As DateTime = Now()
            'Debug.Print("写入账套信息,共花" & (tmpD1 - tmpBeginTime).TotalSeconds)

            '如果返回值为0则出错。
            If ifRet = 0 Then
                MessageBox.Show("保存账套数据时出错。", "账套管理")
                Return
            End If

            If ifInsert Then
                '新增成功
                m_curLedgerEditor.LedgerClass.LedgerId = ifRet
                '要生成一个新的用户数据库

                '拷贝sample.mdb 到 新用户账套文件
                Dim tmpOldTemplate As String = IO.Path.Combine(IO.Path.Combine(sysAppCurrentPath, APP_DATA_PATH), APP_DATA_NAME_TEMPLATE)
                Dim tmpNewMdb As String = IO.Path.Combine(IO.Path.Combine(sysAppCurrentPath, APP_DATA_PATH), l.LedgerClass.LedgerDataRealPath)
                If Not CopyFile(tmpOldTemplate, tmpNewMdb) Then
                    '生成用户账套文件时出错。
                    MessageBox.Show("生成用户账套数据文件时出错。", "账套管理")

                    Return
                End If

                'Dim tmpD2 As DateTime = Now()
                'Debug.Print("拷贝文件,共花" & (tmpD2 - tmpD1).TotalSeconds)

                '第一、建立新账套的访问字串
                Dim tmpNewLedgerConnStr As String = String.Format(sysConnectionTemplate, tmpNewMdb)
                '第二、要拷贝行业模板到新建账户的科目表中
                '第三、设定账套未启用状态
                '第四、要建立账套参数到新建账户的账套参数表中
                If Not SaveNewLedgerSetting(tmpNewLedgerConnStr, m_curLedgerEditor.LedgerClass, m_IndustryAcctType) Then
                    MessageBox.Show("保存当前账套信息时出错。请稍后重试。", "保存账套")
                    Return
                End If

                'Dim tmpD3 As DateTime = Now()
                'Debug.Print("写入账套参数,共花" & (tmpD3 - tmpD2).TotalSeconds)

            End If

            Me.Invoke(m_SaveDone)
            '更新主窗体的通知内容
            sysFrmMdiMain.Invoke(m_ShowNotify, "就绪")

        Catch ex As OleDb.OleDbException
            mErrorCreater = "frmSysManageLedgers - SaveLedgerToDb"
            mErrorMessage = ex.Message
            mErrorNumber = ex.ErrorCode
        End Try

        'Debug.Print("全部写入数据库结束,共花" & (Now() - tmpBeginTime).TotalSeconds)

    End Sub

    Private Function SaveNewLedgerSetting(ByVal connStr As String, ByVal ledger As ClsLedger, ByVal industryType As ClsIndustryAccountType) As Boolean

        'Dim tmpBeginTime As DateTime = Now()
        'Debug.Print("写入开始：" & tmpBeginTime.ToLongTimeString)

        '定义一个账套参数类对象并赋值
        Dim tmpNewLedgerSetting As ClsTLedgerSetting = New ClsTLedgerSetting()
        With tmpNewLedgerSetting
            .CompanyName = ledger.LedgerCompanyName
            .IndustryTypeId = industryType.IndustryId
            .IndustryType = industryType.Industry
            .LedgerOwnerCurrency = "RMB"
            .OneAcctLevelLength = industryType.OneLevelAcctLength
            .LedgerSubAcctLength = industryType.NewAcctLength

            .CashCode = industryType.CashCode
            .BankCode = industryType.BankCode
            .AssetsCode = industryType.AssetsCode
            .DepCode = industryType.DepCode
            .ReceiveCode = industryType.RecieveCode
            .PayCode = industryType.PayCode
            .GainCode = industryType.GainCode
            .DevCode = industryType.DevCode
            .StockCode = industryType.StockCode
            .IncAndDecCode = industryType.IncAndDecCode

            '打印设置
            .IfPrintQuantity = False
            .IfPrintDate = False
            .IfPrintPerson = False
            .IfPrintManager = False
            .IfPrintPoster = False
            .IfPrintNegative = False
            .IfPrintChecker = False
            .IfPrintBankInfo = False
            .IfPrintMaker = False
            .IfPrintCasher = False
            .IfPrintForeignMoney = False
            .IfSelfCheckVoucher = True
            .IfSelfPostVoucher = True

            '启用
            .LedgerIfOpened = False
            .LedgerOpenedDate = DateTime.Now
            .LedgerOpenWorkYear = DateTime.Now.Year.ToString & DateTime.Now().Month.ToString("D2")
            .LedgerWorkYear = .LedgerOpenWorkYear

            'AB账
            .LedgerAbSetup = 0
            .RelativeLedgerId = 0
        End With

        Dim tmpLedgerSettingDb As ClsTLedgerSettingDbAccess = New ClsTLedgerSettingDbAccess(connStr)
        '清空账套参数
        tmpLedgerSettingDb.DeleteAllRecords()
        '写入新账套参数
        If tmpLedgerSettingDb.InsertTLedgerSetting(tmpNewLedgerSetting) = 0 Then
            Return False
        End If

        'Dim tmpD1 As DateTime = Now()
        'Debug.Print("写入参数共花：" & (tmpD1 - tmpBeginTime).TotalSeconds)

        '拷贝行业科目到科目表
        '1、取出指定行业的所有科目集合
        Dim tmpIndustAcctList As List(Of ClsIndustryAccount) = New List(Of ClsIndustryAccount)
        Dim tmpIndustAcctDb As ClsIndustryAccountDbAccess = New ClsIndustryAccountDbAccess(sysAppInfoConnectionString)
        tmpIndustAcctList = tmpIndustAcctDb.GetAllAcctByIndustryId(industryType.IndustryId)
        If tmpIndustAcctList Is Nothing Then
            Return False
        End If

        '2、清空用户科目表中所有内容
        Dim tmpAcctDb As ClsTAccountDbAccess = New ClsTAccountDbAccess(connStr)

        '启用事务，
        Dim tmpError As Boolean = False
        If Not tmpAcctDb.GetConnection().BeginTransaction() Then
            '开启事务出错
        End If

        tmpAcctDb.DeleteAllRecords()

        'Dim tmpD2 As DateTime = Now()
        'Debug.Print("读取行业科目共花：" & (tmpD2 - tmpD1).TotalSeconds)

        '3、循环插入所有模板科目
        For Each tmpIA As ClsIndustryAccount In tmpIndustAcctList
            '生成一个临时TAcct对象
            Dim tmpAcct As ClsTAccount = New ClsTAccount()
            With tmpAcct
                .AccountCode = tmpIA.AcctCode
                .PrevLevelCode = tmpIA.ParentAcctCode
                .Level = tmpIA.AcctLevel
                .AccountName = tmpIA.AcctName
                .ShortName = GetPinYinCaptial(tmpIA.AcctName) '此处使用拼音首字母填充
                If tmpIA.AcctLevel > 1 Then
                    .FullName = GetAcctParentName(tmpIA.ParentAcctCode, tmpIA.IndustryId) & "/" & tmpIA.AcctName  '此字段暂时不做处理
                Else
                    .FullName = tmpIA.AcctName
                End If
                .IfLastLevel = tmpIA.IfLastAcct
                .AccountType = tmpIA.AcctType
                .YearMoney = 0
                .BalanceDirection = IIf(tmpIA.DebitCredit = 1, "借方", "贷方")
                .YearCurrency = 0
                .CurrencyCode = "RMB"
                .IfRateAdjust = False
                .IfQuantity = False
                .QuantityUnit = ""
                .YearQuantity = 0
                .IfProject = False
                .IfCustomer = False
                .IfDepartment = False
                .IfEmployee = False
                .MonthTransit = ""
                .MonthTransitAcctCode = ""
                .AbSet = 0
            End With

            If tmpAcctDb.InsertAccount(tmpAcct) = 0 Then
                tmpError = True
            End If

        Next

        If tmpError Then
            '出错
            tmpAcctDb.GetConnection().RollBackTransaction()
        Else
            tmpAcctDb.GetConnection().CompleteTransaction()
        End If

        'Dim tmpD3 As DateTime = Now()
        'Debug.Print("写入行业科目共花：" & (tmpD3 - tmpD2).TotalSeconds)

        'Debug.Print("全部共花：" & (tmpD3 - tmpBeginTime).TotalSeconds)

        Return True

    End Function

    Private Function GetAcctParentName(ByVal acct As String, ByVal industryId As Integer) As String

        Dim tmpParentName As String = ""

        Dim tmpIndustAcctDb As ClsIndustryAccountDbAccess = New ClsIndustryAccountDbAccess(sysAppInfoConnectionString)
        Dim tmpIndustAcct As ClsIndustryAccount = tmpIndustAcctDb.GetAcctByIdCode(industryId, acct)

        If tmpIndustAcct Is Nothing Then
            Return ""
        Else
            '判断是否需要再上级
            If tmpIndustAcct.AcctLevel > 1 Then
                tmpParentName = GetAcctParentName(tmpIndustAcct.ParentAcctCode, industryId) & "/" & tmpParentName
            Else
                tmpParentName = tmpIndustAcct.AcctName
            End If

            Return tmpParentName
        End If


    End Function

    Private Sub btnClose_Click(sender As Object, e As EventArgs)
        Me.Close()
    End Sub

    Private Sub btnDeleteLedger_Click(sender As Object, e As EventArgs) Handles btnDeleteLedger.Click
        '判断 当前是否有选择的账套
        If m_curLedgerEditor Is Nothing Then
            Return
        End If

        '判断当前账套是否可以删除
        If m_curLedgerEditor.IfOpened And m_curLedgerEditor.IfHaveVoucher Then
            MessageBox.Show("已经使用的账套不可删除。", "账套管理")
            Return

        End If

        '禁止按钮及文本控件
        Me.btnAddLedger.Enabled = False
        Me.btnModifyLedger.Enabled = False
        Me.btnSaveLedger.Enabled = False
        Me.btnDeleteLedger.Enabled = False
        'Me.btnClose.Enabled = False

        Me.txtLedgerName.ReadOnly = True
        Me.txtCompanyName.ReadOnly = True

        '开始删除指定账套
        Dim deleThread As Threading.Thread = New Threading.Thread(AddressOf DeleteCurrentLedger)
        deleThread.Start()
    End Sub

    ''' <summary>
    ''' 删除当前选择的账套
    ''' </summary>
    Private Sub DeleteCurrentLedger()
        Try

            '显示当前操作内容
            sysFrmMdiMain.Invoke(m_ShowNotify, "正在删除指定账套...")

            '第一，从S_Ledger表中删除数据
            Dim tmpLedgerDb As ClsLedgerDbAccess = New ClsLedgerDbAccess(sysAppInfoConnectionString)
            tmpLedgerDb.DeleteLedger(m_curLedgerEditor.LedgerClass)
            '第二，从ListView控件中删除数据

            Me.Invoke(m_deleteRow, New Object() {m_curRow})
            '第三，从m_ledgerListEditor集合列表中删除数据
            m_ledgerEditList.RemoveAt(m_curRow)
            '第四，删除指定文件
            IO.File.Delete(IO.Path.Combine(IO.Path.Combine(sysAppCurrentPath, APP_DATA_PATH), m_curLedgerEditor.LedgerClass.LedgerDataRealPath))
            '第五，修改当前变量m_curLedgerEditor为空或指向下一个
            m_curLedgerEditor = Nothing
            '信息内容置位
            sysFrmMdiMain.Invoke(m_ShowNotify, "就绪")

        Catch ex As Exception
            mErrorCreater = "frmSysManageLedgers - DeleteCurrentLedger"
            mErrorMessage = ex.Message
            mErrorNumber = -2002
        End Try
    End Sub

    Private Sub DeleteRow(ByVal r As Integer)
        If r < 0 OrElse r > Me.lstLedgers.Items.Count - 1 Then
            Return
        End If

        Me.lstLedgers.Items.RemoveAt(r)

        '从控件中删除
        Me.txtCompanyName.Text = ""
        Me.txtLedgerId.Text = ""
        Me.txtLedgerName.Text = ""
        Me.txtLedgerRealPath.Text = ""

        m_editState = 0
        CheckCurrentState()
    End Sub

    Private Sub btnSaveUserLedger_Click(sender As Object, e As EventArgs) Handles btnSaveUserLedger.Click

        '保存当前账套的管理用户信息到数据表中
        Dim tmpLId As Int32
        Dim tmpIdS As List(Of Int32)
        Dim tmpUL As ClsUserLedger
        'Dim tmpList As List(Of ClsUserLedger)

        If m_curLedgerEditor Is Nothing Then
            Return
        End If
        '账套编号 
        tmpLId = m_curLedgerEditor.LedgerClass.LedgerId
        tmpIdS = New List(Of Integer)
        For Each tmpItem As ListViewItem In Me.lstUserLedger.Items
            If tmpItem.Checked Then
                tmpIdS.Add(Integer.Parse(tmpItem.SubItems(0).Text))
            End If
        Next
        If tmpIdS.Count < 1 Then
            Return
        End If

        '保存到当前窗体对象中
        m_curLedgerEditor.UserIdS = tmpIdS

        '保存
        Dim clsUserLedgerDb As ClsUserLedgerDbAccess = New ClsUserLedgerDbAccess(sysAppInfoConnectionString)
        Dim tmpULid As Int32
        'tmpList = New List(Of ClsUserLedger)

        '先删除原有内容
        clsUserLedgerDb.DeleteByLedgerId(tmpLId)

        '保存
        For Each i As Int32 In tmpIdS
            tmpUL = New ClsUserLedger()
            With tmpUL
                .UserId = i
                .LedgerId = m_curLedgerEditor.LedgerClass.LedgerId
                .UserRightFinancialSetup = True
                .UserRightLedger = True
                .UserRightReport = True
                .UserRightSysManage = True
                .UserRightSysSetup = True
                .UserRightVoucher = True
            End With

            '添加到表中
            tmpULid = clsUserLedgerDb.InsertUserLedger(tmpUL)
            tmpUL.UserLedgerId = tmpULid
        Next


    End Sub

    ''' <summary>
    ''' 增加一个新用户
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    Private Sub btnAddUser_Click(sender As Object, e As EventArgs) Handles btnAddUser.Click


        '打开新增窗体
        Dim frmAddUser As frmSysManageAddUser = New frmSysManageAddUser()
        frmAddUser.ShowDialog()

    End Sub

    ''' <summary>
    ''' 选择行业模板来新建账套的回调过程
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e">TransEventArg类，携带选择的行业模板对象，如果返回nothing则表明没有选择</param>
    Private Sub SelectedIndustryTemplate(ByVal sender As Object, ByVal e As TransEventArg)
        '判断是否是需要的回调
        If Not e.Msg.Equals("IndustryAcctType") Then
            Return
        End If

        '判断是否选择了模板
        If e.Obj Is Nothing Then
            '没有选择
            Return
        End If

        m_IndustryAcctType = TryCast(e.Obj, ClsIndustryAccountType)

        If m_IndustryAcctType Is Nothing Then
            Return
        End If

    End Sub

    ''' <summary>
    ''' 新增用户窗体的回调过程。
    ''' 将新用户加入到窗体用户集合列表中。
    ''' 将新用户加入到窗体 userledger集合listview中
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e">TransEventArg类，携带选择的新建用户对象，如果返回nothing则表明没有新建</param>
    Private Sub AddNewUserDone(ByVal sender As Object, ByVal e As TransEventArg)
        '判断是否为 新加用户窗体的回调
        If Not e.Msg.Equals("AddUser") Then
            Return
        End If

        Try

            '取出传递的 ClsUser类对象
            Dim tmpUser As ClsUser = CType(e.Obj, ClsUser)

            '添加到窗体用户有集合中
            m_userList.Add(tmpUser)

            '添加到窗体listview控件中
            Dim tmpItem As ListViewItem = New ListViewItem(tmpUser.UserId)
            tmpItem.SubItems.Add(tmpUser.UserName)

            Me.lstUserLedger.Items.Add(tmpItem)

        Catch ex As Exception
            '调试
            Console.Write(ex.Message)
        Finally

        End Try


    End Sub

    ''' <summary>
    ''' 从锐剑系统中导入账套
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    Private Sub btnInput_Click(sender As Object, e As EventArgs) Handles btnInput.Click
        '导入账套
        '第一步，打开文件
        Dim dlgOpenFile As OpenFileDialog = New OpenFileDialog()
        dlgOpenFile.Filter = "锐剑系统文件 (*.mde)|*.mde"
        dlgOpenFile.Title = "选择锐剑系统文件（账套或备份文件）"
        dlgOpenFile.Multiselect = False
        If dlgOpenFile.ShowDialog() <> DialogResult.OK Then
            Return
        End If

        Dim rjFileName As String = IO.Path.GetFullPath(dlgOpenFile.FileName)
        'Dim rjFileExt As String = IO.Path.GetExtension(dlgOpenFile.FileName)

        '禁用按钮
        Me.btnAddLedger.Enabled = False
        'Me.btnClose.Enabled = False
        Me.btnDeleteLedger.Enabled = False
        Me.btnSaveLedger.Enabled = False
        Me.btnModifyLedger.Enabled = False
        Me.btnInput.Enabled = False

        '阻止窗体被关闭
        m_saving = True

        '在其他线程中运行
        Dim t As Threading.Thread = New Threading.Thread(AddressOf InputMde)
        t.Start(rjFileName)

    End Sub

    Private Delegate Sub InputError(ByVal msg As String)
    Private m_InputError As InputError = New InputError(AddressOf InputMdeError)

    Private Sub InputMdeError(ByVal msg As String)
        m_saving = False

        sysFrmMdiMain.Invoke(m_ShowNotify, "就绪...")

        MessageBox.Show(msg, "导入账套")

        CheckCurrentState()

    End Sub

    Private Delegate Sub InputDone(ByVal newLedgerEdit As ClsLedgerEditor)
    Private m_InputDone As InputDone = New InputDone(AddressOf InputMdeDone)

    Private Sub InputMdeDone(ByVal newLedgerEdit As ClsLedgerEditor)

        m_saving = False


        If newLedgerEdit IsNot Nothing Then
            m_ledgerEditList.Add(newLedgerEdit)
            AddOneLedgerToList(newLedgerEdit)
        End If

        '提示
        MessageBox.Show("成功导入账套。请重新对导入的凭证进行过账及结账。", "导入账套")

        CheckCurrentState()


    End Sub

    Private Sub InputMde(ByVal rjFileName As String)

        'Dim tmpAllBegin As DateTime = DateTime.Now()
        'Debug.Print("总导入开始：" & tmpAllBegin.ToLongTimeString)

        '更新主窗体的通知内容
        sysFrmMdiMain.Invoke(m_ShowNotify, "判断选择的文件是否可以导入...")

        Dim rjFileExt As String = IO.Path.GetExtension(rjFileName)
        Dim inputConnectString As String = String.Format(sysConnectionTemplate, rjFileName)

        '第二步，判断是否为锐剑文件
        Dim rjSoftInfo As RjClsSoftInfo = Nothing
        Dim rjSysNameDb As RjClsSoftInfoDbAccess = New RjClsSoftInfoDbAccess(inputConnectString)



        If rjFileExt.Equals(".mde") Then
            '账套文件
            rjSoftInfo = rjSysNameDb.GetRjCwSoftInfo()
            If rjSoftInfo Is Nothing OrElse rjSoftInfo.StrSoftName.IndexOf("锐剑财务系统") = -1 Then
                'MessageBox.Show("选择的mde文件不是锐剑财务系统的账套文件。", "导入账套")
                Me.Invoke(m_InputError, New Object() {"选择的mde文件不是锐剑财务系统的账套文件。"})
                '返回
                Return
            End If

            '判断是否为注册版本
            If Not rjSoftInfo.IfReged Then
                'MessageBox.Show("非注册版本的锐剑财务系统不能导入账套文件。", "导入账套")
                Me.Invoke(m_InputError, New Object() {"非注册版本的锐剑财务系统不能导入账套文件。"})
                '返回
                Return
            End If
        End If

        '判断是否有凭证，如果没有拒绝生成
        Dim rjVoucherDb As RjClsVoucherDbAccess = New RjClsVoucherDbAccess(inputConnectString)
        Dim rjVoucherCount As Integer = rjVoucherDb.GetVoucherEntryCount()
        If rjVoucherCount < 1 Then
            'MessageBox.Show("没有凭证信息，不能导入账套文件。", "导入账套")
            Me.Invoke(m_InputError, New Object() {"没有凭证信息，不能导入账套文件。"})
            '返回
            Return
        End If

        '更新主窗体的通知内容
        sysFrmMdiMain.Invoke(m_ShowNotify, "正在生成新的账套文件...")

        '生成账套名称
        Dim rjCompanyName As String = Nothing
        Dim rjComNameDb As RjClsMyYearDbAccess = New RjClsMyYearDbAccess(inputConnectString)
        '取公司名称
        rjCompanyName = rjComNameDb.GetRjCompanyName()
        If rjCompanyName Is Nothing Then
            rjCompanyName = "导入账套" & DateTime.Now.ToString()
        End If

        '更新主窗体的通知内容
        sysFrmMdiMain.Invoke(m_ShowNotify, "读取导入文件的信息...")

        '取科目配置信息
        Dim rjAcctSetupDb As RjClsAcctSetupDbAccess = New RjClsAcctSetupDbAccess(inputConnectString)
        Dim rjAcctSetup As RjClsAcctSetup = rjAcctSetupDb.GetRjAcctSetup()

        '取会计期间表
        Dim rjWorkPeriodDb As RjClsWorkPeriodDbAccess = New RjClsWorkPeriodDbAccess(inputConnectString)
        Dim rjOpenWorkPeriod As RjClsWorkPeriod = rjWorkPeriodDb.GetOpenWorkPeriod()
        Dim rjCurWorkPeriod As RjClsWorkPeriod = rjWorkPeriodDb.GetCurWorkPeriod()

        '取凭证类别集合
        Dim rjVTypeDb As RjClsVoucherTypeDbAccess = New RjClsVoucherTypeDbAccess(inputConnectString)
        Dim rjVtypeList As List(Of RjClsVoucherType) = rjVTypeDb.GetAllRecords(Of RjClsVoucherType)

        '取出锐剑科目集合
        Dim rjAcctDb As RjClsAcctDbAccess = New RjClsAcctDbAccess(inputConnectString)
        Dim rjAcctList As List(Of RjClsAccount) = rjAcctDb.GetAllRecords(Of RjClsAccount)("科目编码")

        '找出所有旧表中所有凭证主体信息, 即单独凭证的集合
        'rjVoucherDb = Nothing
        'rjVoucherDb = New RjClsVoucherDbAccess(inputConnectString)
        Dim rjMonthList As List(Of RjClsVoucherBody) = rjVoucherDb.GetAllMonthInVoucher()
        '读取全部的凭证分录集合
        Dim rjAllEntryList As List(Of RjClsVoucher) = rjVoucherDb.GetAllRecords(Of RjClsVoucher)("月份")
        '定义凭证主体字典
        Dim rjAllEntryDict As Dictionary(Of String, String) = New Dictionary(Of String, String)()
        Dim tmpIndex As String = ""
        Dim tmpNextIndex As String = ""
        '将凭证分录信息加入到主体字典中
        For i As Integer = 0 To rjAllEntryList.Count - 1
            tmpIndex = rjAllEntryList(i).Month & "-" & rjAllEntryList(i).VoucherGroup & "-" & rjAllEntryList(i).VoucherNumber
            '判断当前的键值是否存在，存存，则加入，不存在，则添加
            If rjAllEntryDict.ContainsKey(tmpIndex) Then
                rjAllEntryDict(tmpIndex) = rjAllEntryDict(tmpIndex) & i.ToString & ","
            Else
                rjAllEntryDict.Add(tmpIndex, i & ",")
            End If
        Next

        '第三步，导入账套信息
        '3.1生成账套数据文件路径
        '取出账套名称，转换成拼音路径名称
        Dim pinyinS = GetPinYinCaptial(rjCompanyName)
        If pinyinS.Length > 150 Then
            pinyinS = pinyinS.Substring(0, 150)
        End If

        '更新主窗体的通知内容
        sysFrmMdiMain.Invoke(m_ShowNotify, "写入新的账套文件...")

        '新增一个账套记录
        '新增账套
        Dim rjLedger As ClsLedger = New ClsLedger()
        With rjLedger
            .LedgerId = 0
            .LedgerDataRealPath = "l_" & pinyinS & ".mdb"
            .LedgerName = rjCompanyName
            .LedgerCompanyName = rjCompanyName
        End With

        Dim tmpDbAccess As ClsLedgerDbAccess = New ClsLedgerDbAccess(sysAppInfoConnectionString)
        rjLedger.LedgerId = tmpDbAccess.InsertLedger(rjLedger)
        '生成账套的真实数据文件
        '拷贝sample.mdb 到 新用户账套文件
        Dim tmpOldTemplate As String = IO.Path.Combine(IO.Path.Combine(sysAppCurrentPath, APP_DATA_PATH), APP_DATA_NAME_TEMPLATE)
        Dim tmpNewMdb As String = IO.Path.Combine(IO.Path.Combine(sysAppCurrentPath, APP_DATA_PATH), rjLedger.LedgerDataRealPath)
        If Not CopyFile(tmpOldTemplate, tmpNewMdb) Then
            '生成用户账套文件时出错。
            'MessageBox.Show("生成用户账套数据文件时出错。", "导入账套")
            Me.Invoke(m_InputError, New Object() {"生成用户账套数据文件时出错。"})
            '返回
            Return
        End If

        '取出行业科目类型
        Dim industryAcctType As ClsIndustryAccountType = New ClsIndustryAccountTypeDbAccess(sysAppInfoConnectionString).GetIndustryAccountTypeById(rjAcctSetup.IndustryId)

        '建立新账套的访问字串
        Dim rjNewLedgerConnStr As String = String.Format(sysConnectionTemplate, tmpNewMdb)
        '新账套参数操作对象
        Dim tmpLedgerSettingDb As ClsTLedgerSettingDbAccess = New ClsTLedgerSettingDbAccess(rjNewLedgerConnStr)

        '要建立账套参数到新建账户的账套参数表中
        '定义一个账套参数类对象并赋值
        Dim rjLedgerSetting As ClsTLedgerSetting = New ClsTLedgerSetting()
        With rjLedgerSetting
            .LedgerId = rjLedger.LedgerId '账套编号
            .LedgerSettingId = 0 '未取得真实值

            .CompanyName = rjCompanyName
            .IndustryTypeId = rjAcctSetup.IndustryId
            .IndustryType = industryAcctType.Industry
            .LedgerOwnerCurrency = "RMB"
            .OneAcctLevelLength = industryAcctType.OneLevelAcctLength
            .LedgerSubAcctLength = rjAcctSetup.NewAcctLen

            .CashCode = industryAcctType.CashCode
            .BankCode = industryAcctType.BankCode
            .AssetsCode = industryAcctType.AssetsCode
            .DepCode = industryAcctType.DepCode
            .ReceiveCode = industryAcctType.RecieveCode
            .PayCode = industryAcctType.PayCode
            .GainCode = industryAcctType.GainCode
            .DevCode = industryAcctType.DevCode
            .StockCode = industryAcctType.StockCode
            .IncAndDecCode = industryAcctType.IncAndDecCode

            .IfPrintQuantity = False
            .IfPrintForeignMoney = False
            .IfPrintBankInfo = False
            .IfPrintNegative = False
            .IfPrintManager = False
            .IfPrintPoster = False
            .IfPrintChecker = False
            .IfPrintCasher = False
            .IfPrintMaker = False
            .IfPrintPerson = False
            .IfPrintDate = False
            .IfSelfPostVoucher = True
            .IfSelfCheckVoucher = True

            .LedgerIfOpened = True
            .LedgerOpenedDate = DateTime.Parse(rjOpenWorkPeriod.Year & "/" & rjOpenWorkPeriod.Month.ToString & "/1")
            .LedgerWorkYear = rjOpenWorkPeriod.Year & rjOpenWorkPeriod.Month.ToString("D2") 'rjCurWorkPeriod.Year & rjCurWorkPeriod.Month.ToString("D2")
            .LedgerOpenWorkYear = rjOpenWorkPeriod.Year & rjOpenWorkPeriod.Month.ToString("D2")

            .LedgerAbSetup = 0
            .RelativeLedgerId = -1
        End With

        '清空账套参数
        tmpLedgerSettingDb.DeleteAllRecords()
        '写入新账套参数
        If tmpLedgerSettingDb.InsertTLedgerSetting(rjLedgerSetting) = 0 Then
            'MessageBox.Show("写入用户账套数据文件时出错。", "导入账套")
            Me.Invoke(m_InputError, New Object() {"写入用户账套数据文件时出错。"})
            '返回
            Return
        End If

        '更新主窗体的通知内容
        sysFrmMdiMain.Invoke(m_ShowNotify, "正在导入科目数据...")

        '导入凭证类别信息
        Dim rjVTypeDict As Dictionary(Of String, RjClsVoucherType) = New Dictionary(Of String, RjClsVoucherType)()
        Dim tmpVGDb As ClsTVoucherGroupDbAccess = New ClsTVoucherGroupDbAccess(rjNewLedgerConnStr)
        For Each tmpRjType As RjClsVoucherType In rjVtypeList
            rjVTypeDict.Add(tmpRjType.TypeId, tmpRjType)

            Dim rjNewVouGroup As ClsTVoucherGroup = New ClsTVoucherGroup()
            With rjNewVouGroup
                .GroupId = 0
                .GroupName = tmpRjType.VoucherGroup
                .ShortName = tmpRjType.GroupShortName
            End With

            tmpVGDb.InsertGroup(rjNewVouGroup)

        Next

        '第四步，导入科目信息
        '打开新账套科目
        Dim rjNewAcctDb As ClsTAccountDbAccess = New ClsTAccountDbAccess(rjNewLedgerConnStr)
        Dim rjNewAcctList As List(Of ClsTAccount) = New List(Of ClsTAccount)()

        For Each tmpRjAcct As RjClsAccount In rjAcctList
            Dim rjNewAcct As ClsTAccount = New ClsTAccount()
            With rjNewAcct
                .AccountCode = tmpRjAcct.AccountCode     'String '0
                .PrevLevelCode = tmpRjAcct.PrevLevelCode   'String '1
                .Level = tmpRjAcct.Level   'Integer '2
                .AccountName = tmpRjAcct.AccountName    'String '3
                .ShortName = GetPinYinCaptial(tmpRjAcct.AccountName)  'String '4
                .FullName = tmpRjAcct.FullName.Replace("-", "/") & tmpRjAcct.AccountName    'String '5
                .IfLastLevel = tmpRjAcct.IfLastLevel     'Boolean '6
                .AccountType = tmpRjAcct.AccountType     'String   '7 表示科目类型：资产 损益 
                .YearMoney = tmpRjAcct.YearMoney   'Decimal '8
                .BalanceDirection = IIf(tmpRjAcct.BalanceDirection = 1, "借方", "贷方")   'String '9
                .YearCurrency = tmpRjAcct.YearCurrency    'Decimal '10 年初外币
                .CurrencyCode = ""   'String '11 年初外币数
                .IfRateAdjust = False   'Boolean  '12 是否调汇
                .IfQuantity = IIf(tmpRjAcct.SpecialName = "数量", True, False) 'Boolean '13 是否数量核算
                .QuantityUnit = ""   'String '14 数量核算单位
                .YearQuantity = tmpRjAcct.YearQuantity    'Single '15 年初数量
                .IfProject = IIf(tmpRjAcct.SpecialName = "项目", True, False)  'Boolean ' 16 是否核算项目
                .IfCustomer = IIf(tmpRjAcct.SpecialName = "往来", True, False) 'Boolean '17 是否核算往来
                .IfDepartment = IIf(tmpRjAcct.SpecialName = "部门", True, False)   'Boolean '18 是否部门核算
                .IfEmployee = IIf(tmpRjAcct.SpecialName = "员工", True, False) 'Boolean '19 是否职员核算
                .MonthTransit = tmpRjAcct.MonthTransit    'String  '20 月末自动结转方式：借方结转 贷方结转 余额结转
                .MonthTransitAcctCode = tmpRjAcct.MontTransitAcctCode    'String '21 月末结转科目代码
                .AbSet = IIf(tmpRjAcct.Abset = "X", 0, IIf(tmpRjAcct.Abset = "A", 1, 2))  'Int16  '22 AB账设置 0 - 不分， 1- A 2-B -分属AB账
            End With

            rjNewAcctList.Add(rjNewAcct)

        Next

        '清空原科目信息(如果存在）
        rjNewAcctDb.DeleteAllRecords()
        If Not rjNewAcctDb.BatchInsertAcct(rjNewAcctList) Then
            'MessageBox.Show("导入账套科目数据时出错。", "导入账套")
            Me.Invoke(m_InputError, New Object() {"导入账套科目数据时出错。"})
            '返回
            Return
        End If

        '更新主窗体的通知内容
        sysFrmMdiMain.Invoke(m_ShowNotify, "正在导入凭证数据...")

        '第五步，导入凭证信息
        '连续凭证号
        Dim rjMaxNumber As Integer = 0
        Dim rjMonthDict As Dictionary(Of Integer, Integer) = New Dictionary(Of Integer, Integer)()
        Dim rjMonthTypeDic As Dictionary(Of String, Integer) = New Dictionary(Of String, Integer)()
        '写入新表操作对象
        Dim tmpVDDb As ClsTVoucherDetailDbAccess = New ClsTVoucherDetailDbAccess(rjNewLedgerConnStr)
        Dim tmpVDb As ClsTVoucherDbAccess = New ClsTVoucherDbAccess(rjNewLedgerConnStr)
        Dim tmpError As Boolean = False
        '开启事务
        If Not tmpVDb.GetConnection().BeginTransaction() Then
            '开启事务出错
            'MessageBox.Show("开启事务失败，无法导入凭证。", "导入账套")
            Me.Invoke(m_InputError, New Object() {"开启事务失败，无法导入凭证。"})
            '返回
            Return
        End If

        'Dim tmpBeginTime As DateTime = Now()
        'Debug.Print("开始：" & DateTime.Now().ToLongTimeString)

        '5.2找出指定月份所有凭证
        For Each tmpBody As RjClsVoucherBody In rjMonthList

            '5.3找出指定凭证所有分录
            Dim rjEntries As List(Of RjClsVoucher) = New List(Of RjClsVoucher)()
            Dim tmpSumDebit As Decimal = 0
            Dim tmpSumCredit As Decimal = 0

            '取出旧分录
            Dim tmpArrStr As String = rjAllEntryDict(tmpBody.Month & "-" & tmpBody.Type & "-" & tmpBody.Number).Trim()
            If tmpArrStr.Length > 1 Then
                tmpArrStr = tmpArrStr.Substring(0, tmpArrStr.Length - 1)
            End If
            Dim tmpRjEntryArray() As String = tmpArrStr.Split(",")
            '定义新的索引
            For i As Integer = 0 To tmpRjEntryArray.Length - 1
                '添加
                rjEntries.Add(rjAllEntryList(CInt(tmpRjEntryArray(i))))
                tmpSumDebit += rjAllEntryList(CInt(tmpRjEntryArray(i))).Debit
                tmpSumCredit += rjAllEntryList(CInt(tmpRjEntryArray(i))).Credit
            Next

            '5.4生成新的凭证，写入新表中
            Dim tmpVoucher As ClsTVoucher = New ClsTVoucher()
            rjMaxNumber += 1
            With tmpVoucher
                .VoucherAutoId = 0
                .VoucherId = rjMaxNumber
                .WorkPeriod = rjOpenWorkPeriod.Year & tmpBody.Month.ToString("D2")
                .VoucherGroupId = rjVTypeDict(tmpBody.Type).TypeId
                .VoucherGroup = rjVTypeDict(tmpBody.Type).GroupShortName
                .VoucherNumber = tmpBody.Number
                .VoucherDate = DateTime.Parse(rjOpenWorkPeriod.Year & "/" & tmpBody.Month & "/1")
                .Attachment = tmpBody.Attachment
                .Casher = ""
                .Poster = ""
                .Maker = sysCurrentClsUser.UserName '制单变成当前登录用户
                .Checker = ""
                .Hander = ""
                .SumOfDebit = tmpSumDebit
                .SumOfCredit = tmpSumCredit
                .VoucherStatus = "普通"
                .Posted = False
                .Module = "正常"
                .Deleted = False
                .Memo = ""
                .MoneyHz = ConvertNumberToHz(tmpSumDebit)
                .Checked = False
                .EntryList = Nothing
            End With

            '插入到新文件凭证表中
            tmpVoucher.VoucherAutoId = tmpVDb.InsertVoucher(tmpVoucher)
            If tmpVoucher.VoucherAutoId = 0 Then
                tmpError = True
                Exit For
            End If

            '循环旧分录，
            For Each tmpRjEntry As RjClsVoucher In rjEntries
                Dim tmpEntry As ClsTVoucherDetail = New ClsTVoucherDetail()
                With tmpEntry
                    .DetailId = 0 'Integer '0
                    .VoucherId = tmpVoucher.VoucherAutoId 'Integer '1
                    .EntryNumber = tmpRjEntry.Entry  'Integer '2
                    .Excerpta = tmpRjEntry.Exp  'String '3 摘要
                    .AccountCode = tmpRjEntry.AcctCode  'String '4
                    .AccountCodeName = tmpRjEntry.AcctName  'String '5
                    .Debit = tmpRjEntry.Debit  'Decimal '6
                    .Credit = tmpRjEntry.Credit  'Decimal '7
                    .Quantity = tmpRjEntry.Quantity  'Single '8
                    .Price = 0 'Decimal '9
                    .Unit = "" 'String '10
                    .SettleMode = "" 'String '11
                    .SettleCode = "" 'String '12
                    .SettleDate = DateTime.Now() 'DateTime '13
                    .Payer = "" 'String '14
                    .CurrencyCode = "" 'String '15 本位币，默认RMB
                    .ExchangeRate = 0 'Single '16 汇率
                    .CurrencyNumber = 0 'Decimal '17 外币数量
                    .TransCode = IIf(tmpRjEntry.ProjectTrans Is Nothing, "", tmpRjEntry.ProjectTrans)  'String '18 往来业务编号
                    .ProjectName = IIf(tmpRjEntry.ProjectName Is Nothing, "", tmpRjEntry.ProjectName)  'String '19 核算项目名称
                    .ProjectCode = IIf(tmpRjEntry.ProjectCode Is Nothing, "", tmpRjEntry.ProjectCode) 'String '20 核算项目代码
                    .ProjectCustomer = "" 'String '21 核算顶上单位：供应或采购商名称
                    .VoucherNumber = tmpVoucher.VoucherNumber   'Integer '22 凭证本期连续号
                    .VoucherGroupId = rjVTypeDict(tmpRjEntry.VoucherGroup).TypeId  'Integer '23 凭证类别编号 
                    .VoucherGroup = rjVTypeDict(tmpRjEntry.VoucherGroup).GroupShortName   'String '24 凭证类别字号
                    .WorkPeriod = tmpVoucher.WorkPeriod 'string 25 会计期间
                End With

                If tmpVDDb.InsertEntry(tmpEntry) = 0 Then
                    '出错
                    tmpError = True
                    Exit For

                End If
            Next

            '判断是否插入分录时发生错误
            If tmpError Then
                Exit For
            End If

            'TODO:此处判断最大凭证号进行处理
            If rjMonthDict.ContainsKey(tmpBody.Month) Then
                '存在该用数据
                rjMonthDict(tmpBody.Month) = rjMaxNumber
            Else

                rjMonthDict.Add(tmpBody.Month, 1)
                If rjMaxNumber > 1 Then
                    rjMaxNumber = 0
                End If
            End If
            '此处判断凭证类别及凭证号
            If rjMonthTypeDic.ContainsKey(tmpBody.Month & "-" & tmpBody.Type) Then
                '存在，判断当前凭证号是否大于已保存号
                If tmpVoucher.VoucherNumber > rjMonthTypeDic(tmpBody.Month & "-" & tmpBody.Type) Then
                    rjMonthTypeDic(tmpBody.Month & "-" & tmpBody.Type) = tmpVoucher.VoucherNumber
                End If
            Else
                '不存在，则创建
                rjMonthTypeDic.Add(tmpBody.Month & "-" & tmpBody.Type, tmpVoucher.VoucherNumber)

            End If

        Next

        '写入最大凭证号
        Dim tmpMaxOfVoucherDb As ClsTMaxNumberOfVoucherDbAccess = New ClsTMaxNumberOfVoucherDbAccess(rjNewLedgerConnStr)
        Dim tmpMaxOfV As ClsTMaxNumberOfVoucher
        For Each key As Integer In rjMonthDict.Keys
            tmpMaxOfV = New ClsTMaxNumberOfVoucher()
            With tmpMaxOfV
                .WorkPeriod = rjOpenWorkPeriod.Year & key.ToString("D2")
                .VoucherNumber = rjMonthDict(key)
            End With
            '插入新的最大凭证号
            tmpMaxOfVoucherDb.InsertVoucherMaxNumber(tmpMaxOfV)
        Next

        '写入凭证类别对应号码 
        Dim tmpVoucherMaxNumDb As ClsTVoucherMaxNumberDbAccess = New ClsTVoucherMaxNumberDbAccess(rjNewLedgerConnStr)
        Dim tmpVoucherMaxNum As ClsTVoucherNumber
        For Each key As String In rjMonthTypeDic.Keys
            tmpVoucherMaxNum = New ClsTVoucherNumber()
            With tmpVoucherMaxNum
                .VoucherNumberId = 0
                .WorkPeriod = rjOpenWorkPeriod.Year & CInt(key.Substring(0, key.IndexOf("-"))).ToString("D2")
                .GroupShortName = rjVTypeDict(CInt(key.Substring(key.IndexOf("-") + 1))).GroupShortName
                .MaxNumber = rjMonthTypeDic(key)
            End With
            '插入
            tmpVoucherMaxNumDb.InsertMaxNumber(tmpVoucherMaxNum)
        Next

        If tmpError Then
            tmpVDDb.GetConnection().RollBackTransaction()
        Else
            tmpVDDb.GetConnection().CompleteTransaction()
        End If

        'Debug.Print("结束：" & DateTime.Now().ToLongTimeString & "共花费 :" & (DateTime.Now() - tmpBeginTime).ToString)


        '更新主窗体的通知内容
        sysFrmMdiMain.Invoke(m_ShowNotify, "账套成功导入")
        '第六步，提示导入结果
        '更新账套
        Dim tmpNewLedgerEdit As ClsLedgerEditor = New ClsLedgerEditor()
        With tmpNewLedgerEdit
            .LedgerClass = rjLedger
            .IfOpened = True
            .IfHaveVoucher = True
        End With
        'm_ledgerEditList.Add(tmpNewLedgerEdit)
        Me.Invoke(m_InputDone, New Object() {tmpNewLedgerEdit})

        'Debug.Print("总结束：" & DateTime.Now().ToLongTimeString & "共花费 :" & (DateTime.Now() - tmpAllBegin).ToString)

        '更新主窗体的通知内容
        sysFrmMdiMain.Invoke(m_ShowNotify, "就绪")
    End Sub

End Class